package com.hai.mediapicker.activity;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.content.Context;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.io.File;
import java.util.UUID;

import com.github.hiteshsondhi88.libffmpeg.FFmpeg;
import com.github.hiteshsondhi88.libffmpeg.LoadBinaryResponseHandler;
import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandler;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException;

import com.hai.mediapicker.R;
import com.hai.mediapicker.util.SDKUtil;
import com.hai.mediapicker.view.ThumbnailView;
import com.hai.mediapicker.view.MyVideoView;

/**
 * Created by zhaoshuang on 2017/9/30.
 */

public class CutTimeActivity extends Activity{

    private String path;
    private int cutType;
    private Activity mContext;
    private MyVideoView textureView;
    private int videoWidth;
    private int videoHeight;
    private RelativeLayout rl_video;
    private int videoDuration;
    private LinearLayout ll_thumbnail;
    private ThumbnailView thumbnailView;
    private AlertDialog progressDialog;
    private RelativeLayout rl_close;
    private TextView tv_finish_video;
    private int startTime;
    private int endTime;
    private int windowWidth;
    private int windowHeight;
    private ImageView pausePlayButton;

    private AsyncTask thumbsTask;

    private FFmpeg ffmpeg;

    public static final String TAG = "VideoLog-naonao";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;

        Window window = getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        window.setStatusBarColor(Color.parseColor("#1d1d27"));
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);

        setContentView(R.layout.activity_cut_time);
        windowWidth = getWindowManager().getDefaultDisplay().getWidth();
        windowHeight = getWindowManager().getDefaultDisplay().getHeight();

        Intent intent = getIntent();
        path = intent.getStringExtra("path");
        cutType = intent.getIntExtra("cutType", 0);

        loadFFMpegBinary();
        initUI();
    }

    private void initUI() {
        rl_close = (RelativeLayout) findViewById(R.id.rl_close);
        tv_finish_video = (TextView) findViewById(R.id.tv_finish_video);
        textureView = (MyVideoView) findViewById(R.id.textureView);
        rl_video = (RelativeLayout) findViewById(R.id.rl_video);
        ll_thumbnail = (LinearLayout) findViewById(R.id.ll_thumbnail);
        thumbnailView = (ThumbnailView) findViewById(R.id.thumbnailView);
        pausePlayButton = (ImageView) findViewById(R.id.pausePlayButton);
        pausePlayButton.setVisibility(View.GONE);

        pausePlayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(textureView.isPlaying()) {
                    textureView.stop();
                }
                textureView.start();
                textureView.seekTo(startTime);
                pausePlayButton.setVisibility(View.GONE);
            }
        });
        rl_close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        tv_finish_video.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
				executeCutVideoCommand();
            }
        });

        textureView.setVideoPath(path);
        textureView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                textureView.setLooping(false);
                textureView.start();

                videoWidth = textureView.getVideoWidth();
                videoHeight = textureView.getVideoHeight();
                videoDuration = textureView.getDuration();
                endTime = videoDuration;
                startTime = 0;

                initVideoSize();
                initThumbs();
            }
        });

        textureView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            }
        });

        textureView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                pausePlayButton.setVisibility(View.VISIBLE);
            }
        });

        //监听裁剪器滑动
        thumbnailView.setOnScrollBorderListener(new ThumbnailView.OnScrollBorderListener() {
            @Override
            public void OnScrollBorder(float start, float end) {
                changeTime();
            }

            @Override
            public void onScrollStateChange() {
                changeVideoPlay();
            }
        });
    }

    private void loadFFMpegBinary() {
        try {
            if (ffmpeg == null) {
                ffmpeg = FFmpeg.getInstance(this);
				ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
					@Override
					public void onFailure() {
                        Log.e(TAG, "ffmpeg : Incorrect Loaded");
					}

					@Override
					public void onSuccess() {
						Log.v(TAG, "ffmpeg : Correct Loaded");
					}
				});
            }
        } catch (FFmpegNotSupportedException e) {
			Log.e(TAG, e.toString());
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    public TextView showProgressDialog() {
        try{
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setCancelable(false);
            View view = View.inflate(this, R.layout.dialog_loading, null);
            builder.setView(view);
            ProgressBar pb_loading = (ProgressBar) view.findViewById(R.id.pb_loading);
            TextView tv_hint = (TextView) view.findViewById(R.id.tv_hint);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                pb_loading.setIndeterminateTintList(ContextCompat.getColorStateList(this, R.color.dialog_pro_color));
            }
            tv_hint.setText("视频剪切中");
            progressDialog = builder.create();
            progressDialog.show();

            return tv_hint;
        }catch(Exception e) {
            Log.e(TAG, e.toString());
            return null;
        }
    }

    public void closeProgressDialog() {
        try {
            if (progressDialog != null) {
                progressDialog.dismiss();
            }
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    @Override
    public void onPause() {
        releaseResources();
        super.onPause();
    }

    private void releaseResources() {
        if(textureView != null) {
            if(textureView.isPlaying()) {
                textureView.stop();
            }
            textureView.release();
            textureView = null;
        }
        if(thumbsTask != null && thumbsTask.getStatus() == AsyncTask.Status.RUNNING) {
            thumbsTask.cancel(true);
        }
		if(ffmpeg.isFFmpegCommandRunning()) {
            ffmpeg.killRunningProcesses();
        }
		ffmpeg = null;
    }

    private String createVideoName() {
        String videoUUID = UUID.randomUUID().toString().replaceAll("-", "");
        String naonaoPath = SDKUtil.VIDEO_PATH + "/" + videoUUID.substring(0, 5);
        SDKUtil.createDir(naonaoPath);
        return naonaoPath + "/" + videoUUID + ".mp4";
    }

    public static boolean renameFile(String filePath, String rename){
        File file = new File(filePath);
        if(file.exists()){
            File refile = new File(rename);
            if(refile.exists()) {
                refile.delete();
            }
            return file.renameTo(refile);
        }
        return false;
    }

    private void executeCutVideoCommand() {
		String output = (cutType == 0) ?
			createVideoName() : path.substring(0, path.lastIndexOf("/")) + "/cutvideo.mp4";

		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

		String startStr = sdf.format(startTime + 16*60*60*1000);
		String endStr = sdf.format(endTime + 16*60*60*1000);
        String[] complexCommand = {"-ss", startStr, "-t",
                                endStr, "-i", path, "-vcodec",
								"copy", "-acodec", "copy", output};

        execFFmpegBinary(complexCommand, output);
    }

    private void execFFmpegBinary(final String[] command, final String result) {
        try {
            showProgressDialog();
            ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
                @Override
                public void onFailure(String s) {
                    Log.e(TAG, "FAILED with output : " + s);
                }

                @Override
                public void onSuccess(String s) {
                    closeProgressDialog();
					if(null != result && !"".equals(result)){
						Intent intent = new Intent();
						if(cutType != 0) {
							renameFile(result, path);
							intent.putExtra("videoPath", path);
						}else {
							intent.putExtra("videoPath", result);
						}
						setResult(RESULT_OK, intent);
						finish();
					}
                }

                @Override
                public void onProgress(String s) {
                }

                @Override
                public void onStart() {
                    Log.v(TAG, "Started command : ffmpeg ");
                }

                @Override
                public void onFinish() {
                    Log.v(TAG, "Finished command : ffmpeg ");
                }
            });
        } catch (FFmpegCommandAlreadyRunningException e) {
			Log.e(TAG, e.toString());
        }
    }

    /**
     * 更改选择的裁剪区间的时间
     */
    private void changeTime(){

        float left = thumbnailView.getLeftInterval();
        float pro1 = left/ll_thumbnail.getWidth();

        startTime = (int) (videoDuration*pro1);

        float right = thumbnailView.getRightInterval();
        float pro2 = right/ll_thumbnail.getWidth();
        endTime = (int) (videoDuration*pro2);
        endTime = endTime - startTime;
    }

    private void changeVideoPlay(){
    }

    /**
     * 初始化视频播放器
     */
    private void initVideoSize(){

        float ra = videoWidth*1f/videoHeight;

        float widthF = videoWidth*1f/720;
        float heightF = videoHeight*1f/1280;
        ViewGroup.LayoutParams layoutParams = textureView.getLayoutParams();
        // layoutParams.width = (int) (windowWidth*widthF);
        // layoutParams.height = (int) (layoutParams.width/ra);
        textureView.setLayoutParams(layoutParams);

        //最小剪切时间500毫秒
        int pxWidth = (int) (3000f/videoDuration*thumbnailView.getWidth());
        thumbnailView.setMinInterval(pxWidth);
    }

    /**
     * 初始化缩略图
     */
    private void initThumbs(){

        final int frame = 15;
        final int frameTime = videoDuration/frame*1000;

        int thumbnailWidth =  ll_thumbnail.getWidth()/frame;
        for (int x=0; x<frame; x++){
            ImageView imageView = new ImageView(this);
            imageView.setLayoutParams(new ViewGroup.LayoutParams(thumbnailWidth, ViewGroup.LayoutParams.MATCH_PARENT));
            imageView.setBackgroundColor(Color.parseColor("#666666"));
            imageView.setScaleType(ImageView.ScaleType.CENTER);
            ll_thumbnail.addView(imageView);
        }

        thumbsTask = new AsyncTask<Void, Void, Boolean>() {
            @Override
            protected Boolean doInBackground(Void... params) {
                MediaMetadataRetriever mediaMetadata= new MediaMetadataRetriever();
                mediaMetadata.setDataSource(mContext, Uri.parse(path));
                for (int x=0; x<frame; x++){
                    if(isCancelled()) {
                        break;
                    }
                    Bitmap bitmap = mediaMetadata.getFrameAtTime(frameTime*x, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                    Message msg = myHandler.obtainMessage();
                    msg.obj = bitmap;
                    msg.arg1 = x;
                    myHandler.sendMessage(msg);
                }
                mediaMetadata.release();
                return true;
            }
            @Override
            protected void onPostExecute(Boolean result) {
            }
        }.execute();
    }

    private Handler myHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            ImageView imageView = (ImageView) ll_thumbnail.getChildAt(msg.arg1);
            Bitmap bitmap = (Bitmap) msg.obj;
            if(imageView!=null && bitmap!=null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    };
}
